package org.example.spring02aop.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Aspect
@Component

public class AroundAspect {

    /*
    * 环绕通知固定写法如下：
    * Object：返回值
    */

    //ProceedingJoinPoint：可推进的连接点

    @Pointcut("execution(int *(int,int))")
    public void pointCut()
    {

    }

    @Around("pointCut()")

    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        Object[] args = joinPoint.getArgs();//拿到目标对象的参数列表

        //前置
        System.out.println("【环绕 - 前置通知】，参数："+ Arrays.toString( args));
        Object proceed = null;

        try{
            //接受传入参数的proceed，实现修改目标方法执行用的参数
            proceed = joinPoint.proceed(args);//继续执行目标法昂夫；~~ 反射 method.invoke()
            //返回
            System.out.println("【环绕 - 返回通知】，返回值："+proceed);
        }catch (Throwable e){
            //异常
            System.out.println("【环绕 - 异常通知】"+e.getMessage());
            throw e;//抛出异常:防止让外层继续感知
        }finally {
            //后置
            System.out.println("【环绕 - 后置通知】");
        }

        return proceed;
    }
}
